
using System;

using System.Drawing;
using System.Windows.Forms;

using System.IO;
using System.Threading;
using System.Diagnostics;

using System.Data;
using System.Reflection;

using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Runtime.InteropServices;

using Microsoft.VisualBasic.ApplicationServices;

using System.Deployment.Application;

using System.Text.RegularExpressions;

using System.ComponentModel;

using needle.Services.soab;

using needle.UI;

namespace needle {

    class Foreground {

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        public static bool Instance(string name) {
            System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(name);

            foreach (System.Diagnostics.Process process in processes) {
                if (process.MainWindowHandle != (IntPtr)0) {
                    SetForegroundWindow(process.MainWindowHandle);
                    return true;
                }
            }
            return false;
        }
    }

    class NeedleLoader : Loader<Needle> {

        public NeedleLoader() : base() {}

        public override Needle CreateNeedle() {
            Needle needle = new Needle();
            return needle;
        }

    }

    class Loader<T> {
        public virtual T CreateNeedle() {
            return default(T);
        }
    }

	public class Start {

        private static Needle __Needle = null;
        
		public Start() {}

        // [MTAThread] //
        [STAThread]
        static void Main(string[] arguments)
        {

            if (Define.Options.Secure) {
                if (Foreground.Instance(Application.ProductName)) {
                    return;
                }
            }

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);
            Application.SetCompatibleTextRenderingDefault(true);

            SingleInstanceApplication application = new SingleInstanceApplication();
            application.StartupNextInstance += Start.OnStartupNextInstance;

            Splash.StartSplash("needle_shin.png", Color.FromArgb(0, 0, 255, 0));
            //Splash.StartSplash("needle_letany.png", Color.FromArgb(255, 255, 255, 255));

            // simulating operations at startup
            System.Threading.Thread.Sleep(3000);

            __Needle = (new NeedleLoader()).CreateNeedle();
           // __Needle.ShowDialog(); 

            // close the splash screen
            Splash.CloseSplash();

            if (Define.Options.Online)
                OfflineApplicationBlock.Initialize();

            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            //Application.Run(__Needle);

            SingleInstanceApplication __Application = new SingleInstanceApplication();

            __Application.StartupNextInstance += new StartupNextInstanceEventHandler(OnStartupNextInstance);
            __Application.Run(__Needle);

            //Application.ThreadException -= new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

            if (Define.Options.Online)
                OfflineApplicationBlock.Terminate();

        }

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {

            MessageBox.Show(
                e.Exception.ToString(),
                Application.ProductName,
                MessageBoxButtons.OK,
                MessageBoxIcon.Error
                );

        }

        private static void OnStartupNextInstance(object sender, StartupNextInstanceEventArgs e) {
            // an attempt to start the application a second time has been made
            try {
                if (__Needle != null) {
                    // activate the main application window
                    if (__Needle.WindowState == FormWindowState.Minimized) {
                        __Needle.WindowState = FormWindowState.Normal;
                    }
                    __Needle.Activate();
                }
                // handle any command-line args
                __Needle.NeedleOpen(e.CommandLine);
            }
            catch (Exception ex) {
                Debug.WriteLine(ex);
                MessageBox.Show(ex.ToString());
            }
        }

    }
}